package com.mk.service.web;

import act.apidoc.Description;
import act.controller.Controller;
import act.event.ActEvent;
import act.event.EventBus;
import act.event.On;
import act.inject.DefaultValue;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSONObject;
import com.github.d925529.apidoc.ApiHttpMethod;
import com.github.d925529.apidoc.annotation.*;
import com.mk.Starter;
import com.mk.domain.CpUser;
import com.mk.domain.TOrder;
import com.mk.enums.GlobalValues;
import com.mk.enums.PayValues;
import com.mk.exception.UserException;
import com.mk.interceptor.ITranslate;
import com.mk.util.*;
import com.mk.util.pay.PayUtils;
import com.sun.org.apache.xpath.internal.operations.Bool;
import jdk.nashorn.internal.objects.Global;
import org.osgl.http.H;
import org.osgl.mvc.annotation.GetAction;
import org.osgl.mvc.annotation.PostAction;
import org.osgl.mvc.annotation.With;
import org.osgl.util.C;
import org.osgl.util.S;

import javax.inject.Inject;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;


@SuppressWarnings("all")
@Controller("pay")
@Api(group = "wb", title = "支付服务接口", path = "pay")
public class WXService extends BaseWebService {
    @Inject
    private CpUser.Mapper cpUserMapper;
    @Inject
    private TOrder.Mapper torderMapper;
    @Inject
    private EventBus eventBus;


    @PostAction("wxPayResult.json")
    @ApiMethod(title = "微信支付回调通用服务", path = "/wxPayResult.json", method = ApiHttpMethod.POST)
    @ApiReturn(description = "返回支付通知处理结果,如:<xml>\n" +
        "  <return_code><![CDATA[SUCCESS]]></return_code>\n" +
        "  <return_msg><![CDATA[OK]]></return_msg>\n" +
        "</xml>", type = String.class)
    public void wxPayResult(H.Response resp) {
        Map<String, String[]> notifyParams = context.allParams();
        Map<String, String> notifyParam = PayUtils.getNotifyParam(notifyParams);
        PayUtils payUtils = PayUtils.getPayUtils(GlobalValues.PAY_TYPE_WEIXIN.value());
        Map<String, Object> result = payUtils.payCallback(notifyParam, context);
        // 触发之前缓存的事件
        eventBus.trigger(MapUtil.getStr(result, "event"), new ActEvent<>(result));
        String resultStr = PayUtils.returnWxXML();
        resp.header("Content-Type", "text/xml").output().append(resultStr).close();
    }


    @With({WbILogin.class, ITranslate.class})
    @GetAction("getPayObj.json")
    @ApiMethod(title = "获取支付对象", path = "/getPayObj.json", method = ApiHttpMethod.GET)
    @ApiParam(name = "paytype", title = "支付类型:WX(微信支付),UN银联支付", type = String.class)
    @ApiParam(name = "orderid", title = "支付订单id", type = String.class)
    @ApiParam(name = "resulturl", title = "支付结果页链接", type = String.class)
    @ApiParam(name = "tradetype", title = "交易类型,微信支付时使用:JSAPI 公众号支付;NATIVE 扫码支付;APP APP支付(默认为JSAPI)", type = String.class)
    @ApiReturn(description = "返回支付下单返回的内容", type = Map.class, maps = {
        @ApiMap(name = "appId", title = "公众号appid", type = String.class),
        @ApiMap(name = "timestamp", title = "时间戳", type = String.class),
        @ApiMap(name = "nonceStr", title = "随机字符串", type = String.class),
        @ApiMap(name = "package", title = "区分业务逻辑ShopOrder充值会员,UserOrder用户下单", type = String.class),
        @ApiMap(name = "signType", title = "签名类型", type = String.class),
        @ApiMap(name = "paySign", title = "支付签名", type = String.class)
    })
    public Map<String, String> getPayObj(@Description("支付类型") @DefaultValue("WX") String paytype,
                                         @Description("订单号") String orderid,
                                         @Description("支付结果页链接") String resulturl,
                                         @Description("交易类型,微信支付时使用:JSAPI 公众号支付;NATIVE 扫码支付;APP APP支付") @DefaultValue("JSAPI") String tradetype) {

        //region 生成订单
        Map<String,Object> orderMap=torderMapper.queryOrderInfo(orderid);
        //endregion

        PayUtils payUtils = PayUtils.getPayUtils(paytype);
        //region 支付参数
        Map<String, String> paramMap = new HashMap<>();
        paramMap.put("body", MapUtil.getStr(orderMap,"pdnames"));
        paramMap.put("out_trade_no", MapUtil.getStr(orderMap,"paynumber"));
        //orderMap.put("orderamount",new BigDecimal(0.01));
        paramMap.put("total_fee", MapUtil.get(orderMap,"orderamount").toString());
        paramMap.put("originalprice", MapUtil.get(orderMap,"originalprice").toString());
        paramMap.put("ipAddress", this.context.req().ip());
        // me.setOpenid("okSYiwXW0LwuBL_WYxfBrNSm6EoU");
        paramMap.put("openid", me.getOpenid());
        paramMap.put("resulturl", resulturl);
        //endregion
        //region 支付对象
        Map<String, String> attach = new HashMap<>();
        attach.put("orderid", MapUtil.getStr(orderMap,"orderid"));
        attach.put("event", PayValues.PAT_EVENT_NAME_BUY_PRODUCT);
        paramMap.put("attach", "1");
        //endregion
        // 缓存支付对象
        Redis.payDb.getBucket(MapUtil.getStr(orderMap,"paynumber"), Map.class).set(attach, 2, TimeUnit.DAYS);

        Map<String, String> objMap;
        try {
            objMap = payUtils.getPayObject(paramMap);
        } catch (Exception ex) {
            Starter.LOG.error(S2.getFullError(ex));
            throw new UserException("订单有误，请确认后重试！");
        }
        return objMap;
    }



    /**
     * 异步处理支付结果
     * 监听特定事件
     */
    @On(value = "支付结果事件名称,定义在PayValues中")
    @With(ITranslate.class)
    public void buyVipResult(ActEvent<Map<String, Object>> event) {
        // 缓存的支付对象
        Map<String, Object> map = event.source();
    }


    @GetAction("wxConfigSign.json")
    @ApiMethod(title = "url签名", path = "/wxConfigSign.json", method = ApiHttpMethod.GET)
    @ApiParam(name = "url", title = "待签名的url", type = String.class)
    @ApiReturn(description = "返回支付下单返回的内容", type = Map.class, maps = {
        @ApiMap(name = "appId", title = "公众号appid", type = String.class),
        @ApiMap(name = "timestamp", title = "时间戳", type = String.class),
        @ApiMap(name = "nonceStr", title = "随机字符串", type = String.class),
        @ApiMap(name = "signature", title = "签名类型", type = String.class),
    })
    public Map<String, Object> wxConfigSign(@Description("签名的链接") String url) {
        return WechatUtils.getJSSDKConfig(url);
    }

    @PostAction("unPayResult.json")
    @ApiMethod(title = "银联支付回调通用服务", path = "/unPayResult.json", method = ApiHttpMethod.POST)
    @ApiReturn(description = "返回银联支付通知处理结果,", type = String.class)
    public void unPayResult(H.Response resp) {
        Map<String, String[]> notifyParams = context.allParams();
        Map<String, String> notifyParam = PayUtils.getNotifyParam(notifyParams);
        notifyParam.remove("_body");
        PayUtils payUtils = PayUtils.getPayUtils(GlobalValues.PAY_TYPE_UNION.value());
        Map<String, Object> result = payUtils.payCallback(notifyParam, context);
        // 触发之前缓存的事件
        eventBus.trigger(MapUtil.getStr(result, "event"), new ActEvent<>(result));
        resp.output().append("SUCCESS").close();
    }


    @GetAction("getOrderIdByPayid.json")
    @ApiMethod(title = "根据payid返回orderid", path = "/getOrderIdByPayid.json", method = ApiHttpMethod.GET)
    @ApiParam(name = "payid", title = "支付id", type = String.class)
    @ApiReturn(description = "根据payid返回orderid,", type = String.class)
    public Map<String,Object> getOrderIdByPayid(String payid) {
        if(S.empty(payid)){
            return C.Map("orderid","");
        }

        Map<String,Object> map = torderMapper.queryOrderInfo(payid);
        return map;
    }

    public static void main(String[] args) {
        PayUtils payUtils=PayUtils.getPayUtils(GlobalValues.PAY_TYPE_UNION.value());
        Map<String,String> param=new HashMap<>();
        param.put("orderid","PAY201811051731113670203");
        Map<String,String> map=payUtils.getOrderInfo("PAY201811091042535948279");
        System.out.println("dd");
    }
}
